const sessionCache = require('idiv-utils').sessionCache;

const historyStack = (function () {
	let
		isDirectUrl = false,
		prevHistoryLength = window.history.length,
		historyChangeCallBck = null,
		historyCache = null;

	const
		getHistoryStack = function () {
			historyCache = historyCache || sessionCache.get('historyStack');
			if (!historyCache || window.history.length === 1) {
				historyCache = {
					routerArr: [],
					isBack: false,
					isFresh: false,
					isForward: true,
				};
				sessionCache.put('historyStack', historyCache);
			}
			return historyCache;
		},
		
		handleRouter = function () {
			let url = window.location.href;
			const
				historyStack = getHistoryStack(),
				routerArr = historyStack.routerArr,
				len = routerArr.length,
				historyLength = window.history.length,
				index = routerArr.lastIndexOf(url);

			historyStack.isBack = false;
			historyStack.isFresh = false;
			if (isLoading) {
				if (url === routerArr[len - 2]) {
					url = modifyUrlParmas(url, 'historyCount', ++historyStack.count);
					window.history.replaceState(null, '', url);
				}

				routerArr[len - 1] = url;
				sessionCache.put('historyStack', historyStack);
				return historyStack;
			}
			// 页面前进
			if (index === -1) {
				historyStack.isForward = true;
				prevHistoryLength = historyLength;
				historyStack.routerArr.push(url);
				sessionCache.put('historyStack', historyStack);
				return historyStack;
			}

			// 判断前进或者后退按钮; 有一种情况判断不出, 输入链接之后返回再输入
			if (prevHistoryLength === historyLength) {
				if (index === len - 1) {
					historyStack.isFresh = true;
					historyStack.isForward = false;
				} else if (index === len - 2) {
					historyStack.isBack = true;
					historyStack.isForward = false;
					routerArr.pop();
					historyStack.prevPosition = scrollArr.pop();
				} else {
					historyStack.isForward = true;
					historyStack.isBack = false;
					routerArr.push(url);
				}
				sessionCache.put('historyStack', historyStack);
				return historyStack;
			}

			historyStack.isForward = true;
			if (index === len - 2 || index === len - 1) {
				url = modifyUrlParmas(url, 'historyCount', ++historyStack.count);
				history.replaceState(null, '', url);
			}

			prevHistoryLength = historyLength;
			routerArr.push(url);
			sessionCache.put('historyStack', historyStack);
			return historyStack;
		},
		recordScrollY = function() {
			const
				historyStack = gethistoryStack(),
				routerArr = historyStack.routerArr,
				scrollArr = historyStack.scrollArr;
			if(scrollArr.length < routerArr.length) {
				scrollArr.push(window.scrollY);
			} else {
				scrollArr.length = routerArr.length;
			}
			sessionCache.put('historyStack', historyStack);
		},
		calculateScrollY = function() {
			const
				historyStack = gethistoryStack(),
				scrollArr = historyStack.scrollArr;

			if(historyStack.isBack) {
				historyStack.prevPosition = scrollArr.pop();
			}

			sessionCache.put('historyStack', historyStack);
			return historyStack;
		},
		listenHistory = function () {
			handleRouter();
			const historyStack = calculateScrollY();
			if (historyStack && historyChangeCallBck) {
				historyChangeCallBck(historyStack);
			}
		};
		
	return {
		listenHistory: handleRouter,
		directUrl(url, isReplace = false, isHref = true) {
			let
				historyStack = null,
				routerArr = [],
				len = 0,
				steps = 0,
				index = -1,
				isForward = false;

			isDirectUrl = true;
			prevHistoryLength = window.history.length;
			if (url[0] === '#') {
				url = window.location.href.replace(/#.+/, url);
			}

			// 不支持replaceState就用location的代理
			if (!window.history.replaceState) {
				if (isReplace) {
					window.location.replace(url);
				} else {
					window.location.href = url;
				}
				return false;
			}

			historyStack = gethistoryStack();
			routerArr = historyStack.routerArr;
			len = routerArr.length;
			index = routerArr.lastIndexOf(url);
			isForward = isHref || index === -1;

			historyStack.isFresh = false;
			historyStack.isForward = isForward || isReplace;
			switch (true) {
				case isReplace:
					historyStack.routerArr[len - 1] = url;
					sessionCache.put('historyStack', historyStack);
					window.location.replace(url);
					break;
				case isForward:
					// 前进
					historyStack.isBack = false;
					sessionCache.put('historyStack', historyStack);
					window.location.href = url;
					break;
				case !isForward:
					// 这种情况认为是返回
					historyStack.isBack = true;
					steps = index - routerArr.length + 1;
					historyStack.routerArr = routerArr.slice(0, index + 1);
					sessionCache.put('historyStack', historyStack);
					steps && window.history.go(steps);
					break;
				default:
					throw Error('入参有误！');
			}
			// 执行注入的回调
			historyChangeCallBck && historyChangeCallBck(historyStack);
		},
		hasRegisterListener: false,
		listen: function() {
			
		}
		setHistory(listen, listenBefore) {
			if (this.hasRegisterListener) return;

			if(typeof listen === 'function') {
				listen(listenHistory);
			}

			if(typeof listenBefore === 'function') {
				listenBefore(recordScrollY);
			}
			
			window.removeEventListener('beforeunload', recordScrollY);
			window.addEventListener('beforeunload', recordScrollY, false);
			this.hasRegisterListener = true;
		},
		destroy() {
			delete window.sessionStorage.historyStack;
			window.removeEventListener('beforeunload', recordScrollY);
			this.hasRegisterListener = false;
		},
		registerHistoryLitener(fn) {
			historyChangeCallBck = fn;
		},
		gethistoryStack() {
			return gethistoryStack();
		},
	};
}());


module.exports = historyStack;